package com.talos.framework.common.validation;


import com.talos.framework.common.annotation.IDCard;
import com.talos.framework.common.constant.RegexConstant;
import com.talos.framework.common.util.collection.EmptyUtils;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.metadata.ConstraintDescriptor;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidator;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IDCardValidator implements HibernateConstraintValidator<IDCard, String> {

    private static final Pattern PATTERN = Pattern.compile(RegexConstant.ID_CARD);

    private static final int[] FACTOR = new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

    private static final char[] PARITY = new char[]{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

    @Override
    public void initialize(IDCard constraintAnnotation) {

    }

    @Override
    public void initialize(ConstraintDescriptor<IDCard> constraintDescriptor, HibernateConstraintValidatorInitializationContext initializationContext) {

    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (EmptyUtils.isEmpty(value)) {
            return true;
        }

        Matcher matcher = PATTERN.matcher(value);

        if (!matcher.matches()) {
            return false;
        }

        int sum = 0;

        char[] charArray = value.toCharArray();

        for (int i = 0; i < 17; i++) {
            sum += (charArray[i] - '0') * FACTOR[i];
        }

        char lastChar = PARITY[sum % 11];

        return lastChar == charArray[17];
    }

}

